from flask import Flask, request, jsonify, make_response
from user_manager import DummyUserManager
from jassjwt import JaaSJwtBuilder
import jwt
from functools import wraps
import datetime as dt
from werkzeug.security import generate_password_hash, check_password_hash
from flask_cors import CORS
from jwt_jitsi import jitsi_opensource_mock_shared_secret

user_manager = DummyUserManager()

app = Flask(__name__)
CORS(app)
app.config['SECRET_KEY'] = 'meowingful'

@app.route('/api/ping')
def index():
    return {"hello": "meowingfull day isn't it"}


# decorator for verifying the JWT
def token_required(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        token = None
        # jwt is passed in the request header
        if 'x-access-token' in request.headers:
            token = request.headers['x-access-token']
        # return 401 if token is not passed
        if not token:
            return jsonify({'message': 'Token is missing !!'}), 401

        try:
            # decoding the payload to fetch the stored details
            data = jwt.decode(token, app.config['SECRET_KEY'], algorithms="HS256")
            current_user = user_manager.get_user(data['public_id']).get_public_user()
            # current_user = User.query \
            #     .filter_by(public_id=data['public_id']) \
            #     .first()
        except Exception as e:
            print(e)
            return jsonify({
                'message': 'Token is invalid !!'
            }), 401
        # returns the current logged in users contex to the routes
        return f(current_user, *args, **kwargs)
    return decorated


@app.route('/api/me', methods=['GET'])
@token_required
def get_current_user(current_user):
    """
    it work because f(current_user, *args, **kwargs)
    :param current_user:
    :return:
    """
    return jsonify({'current_user': current_user})


@app.route('/api/jwt_jaas_8x8', methods=['GET'])
def demo_jaas_token():
    PRIVATE_KEY = "/home/tt/key/jitsi/jitsi.private"
    PUBLIC_KEY = "/home/tt/key/jitsi/jitsi.pub"
    key_content = open(PRIVATE_KEY).read()
    pubkey_content = open(PUBLIC_KEY).read()

    jaasJwt = JaaSJwtBuilder()  # Create new JaaSJwtBuilder and setup the claims.

    token = jaasJwt.withDefaults() \
        .withApiKey("vpaas-magic-cookie-2c39fbf723dc401b89e2f666fa7e6ace/cca7c6") \
        .withUserName("ttpro1995") \
        .withUserEmail("ttpro1995@gmail.com") \
        .withModerator(True) \
        .withAppID("vpaas-magic-cookie-2c39fbf723dc401b89e2f666fa7e6ace") \
        .withUserAvatar("https://asda.com/avatar") \
        .signWith(key_content)  # Pass the private here
    print(token)
    print(type(token))
    print(token.decode("utf-8"))
    token_str = token.decode("utf-8")
    return {"jitsi_jwt": token_str}


@app.route('/api/jwt_jaas_8x8_user', methods=['POST'])
@token_required
def demo_jaas_token_with_user(current_user):
    print(current_user)

    appid = "vpaas-magic-cookie-2c39fbf723dc401b89e2f666fa7e6ace"
    content = request.json
    username = current_user["username"]
    email = username + "@emeow.com"
    room = content["room"]
    roomname = appid + "/" + room
    PRIVATE_KEY = "/home/tt/key/jitsi/jitsi.private"
    PUBLIC_KEY = "/home/tt/key/jitsi/jitsi.pub"
    key_content = open(PRIVATE_KEY).read()
    pubkey_content = open(PUBLIC_KEY).read()

    jaasJwt = JaaSJwtBuilder()  # Create new JaaSJwtBuilder and setup the claims.

    token = jaasJwt.withDefaults() \
        .withApiKey("vpaas-magic-cookie-2c39fbf723dc401b89e2f666fa7e6ace/cca7c6") \
        .withUserName(username) \
        .withUserEmail(email) \
        .withModerator(True) \
        .withAppID("vpaas-magic-cookie-2c39fbf723dc401b89e2f666fa7e6ace") \
        .withUserAvatar("https://i.imgur.com/Jvh1OQm.jpg") \
        .signWith(key_content)  # Pass the private here
    print(token)
    print(type(token))
    print(token.decode("utf-8"))
    token_str = token.decode("utf-8")
    return {"jitsi_jwt": token_str, "username": username, "roomname": roomname, "email": email}

@app.route('/api/jwt_jitsi_sangatel', methods=['POST'])
@token_required
def demo_sangatel_token_with_user(current_user):
    print(current_user)

    appid = "meet-sangatel"
    content = request.json
    username = current_user["username"]
    email = username + "@emeow.com"
    room = content["room"]
    # roomname = appid + "/" + room
    roomname =  room
    PRIVATE_KEY = "/home/tt/key/jitsi/jitsi.private"
    PUBLIC_KEY = "/home/tt/key/jitsi/jitsi.pub"
    # key_content = open(PRIVATE_KEY).read()
    # pubkey_content = open(PUBLIC_KEY).read()
    token = jitsi_opensource_mock_shared_secret(room, username)

    return {"jitsi_jwt": token, "username": username, "roomname": roomname, "email": email}


# route for loging user in
@app.route('/api/login', methods=['POST'])
def login():
    # creates dictionary of form data
    auth = request.form

    if not auth or not auth.get('username') or not auth.get('password'):
        # returns 401 if any email or / and password is missing
        return make_response(
            {"error": -1, 'error_msg': 'Could not verify'},
            400,
            {'WWW-Authenticate': 'Basic realm ="Login required !!"'}
        )

    user = user_manager.get_user_by_username(auth.get("username"))

    if not user:
        # returns 401 if user does not exist
        return make_response(
            {"error": -1, 'error_msg': 'Could not verify'},
            400,
            {'WWW-Authenticate': 'Basic realm ="User does not exist !!"'}
        )

    if check_password_hash(user.password, auth.get('password')):
        # generates the JWT Token
        token = jwt.encode({
            'public_id': user.id,
            'username': user.username,
            'exp': dt.datetime.utcnow() + dt.timedelta(minutes=30)
        }, app.config['SECRET_KEY'], algorithm="HS256")

        return make_response(jsonify({'error': 0, 'token': token}), 201)
    # returns 403 if password is wrong
    return make_response(
        {"error": -1, 'error_msg': 'Could not verify'},
        400,
        {'WWW-Authenticate': 'Basic realm ="Wrong Password !!"'}
    )


if __name__ == '__main__':
    app.run(port=3000)
